package com.tansun.ruledata.sessionpool;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.impl.KnowledgeBaseFactory;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderError;
import org.kie.internal.builder.KnowledgeBuilderErrors;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.conf.MultithreadEvaluationOption;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.config.AppConfiguration;
import com.tansun.ruledata.data.entity.DeployVersionInfo;

public class RuleDataPooledSessionFactory extends BasePooledObjectFactory<KieSession> {
	
	private  KieBase kieBase;
	
	private static final   Logger  logg = LoggerFactory.getLogger(RuleDataPooledSessionFactory.class);
	
	public static synchronized RuleDataPooledSessionFactory buildPooledSessionFactoryByDataRuleProj(Collection<DeployVersionInfo>  list,String enterPoint) throws Exception{
		RuleDataPooledSessionFactory psf = new RuleDataPooledSessionFactory();
		psf.initKe(list,enterPoint);
		return psf ;
	}
	
	
	public   void initKe(Collection<DeployVersionInfo>  list,String enterPoint){
		  KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();  

          if (list != null){
              List<String>  drlList  = new ArrayList<>();
              List<String> bpmList  = new  ArrayList<>();
        	  for (DeployVersionInfo ruleVersionVO :list){
	                  if (RuleModelTypeEnum.RuleFlow.code.equals(ruleVersionVO.getModelType())){
	                	  bpmList.add(ruleVersionVO.getRuleContent());
	                  }else if (RuleModelTypeEnum.ExecutionBlock.code.equals(ruleVersionVO.getModelType())){
	                	  bpmList.add(ruleVersionVO.getRuleContent());	 
	                  } 	  
	                  else if (RuleModelTypeEnum.CodeBlock.code.equals(ruleVersionVO.getModelType())){
		                	  continue;	                	   	  
	                  }else
	                	  kb.add(ResourceFactory.newByteArrayResource(ruleVersionVO.getRuleContent().getBytes()),ResourceType.DRL);
	                  drlList.add(ruleVersionVO.getDrlFile());

        	  }
        	  for  (String  bStr : bpmList) {
        		  kb.add(ResourceFactory.newByteArrayResource(bStr.getBytes()),ResourceType.BPMN2);
        	  }
        	  if (drlList.size()>0){
        		  AppConfiguration.deployDrlList.put(enterPoint, drlList);
        	  }
          }
	      KnowledgeBuilderErrors errors = kb.getErrors();
	      for (KnowledgeBuilderError error:errors) {
	    	  System.out.println(error.getMessage());
	      }
		  KieBaseConfiguration kbconfig = KieServices.Factory.get().newKieBaseConfiguration();
	  	  kbconfig.setProperty("drools.consequenceExceptionHandler", "com.tansun.rule.exception.RuleConsequenceExceptionHandler");	
	  	  //kbconfig.setOption(MultithreadEvaluationOption.YES);
	      InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(kbconfig); 
	      kBase.addPackages(kb.getKnowledgePackages()); 
	      kieBase= kBase;
		  
	}
	
	public void init(Collection<DeployVersionInfo>  list,String enterPoint) throws Exception {
          KieHelper  kieHelper  = new  KieHelper();
  
          if (list != null){
              List<String>  drlList  = new ArrayList<>();
        	  for (DeployVersionInfo ruleVersionVO :list){
        		  if(RuleModelTypeEnum.DataComponet.getCode().equals(ruleVersionVO.getModelType()))
        			  continue;
        		  try {
	                  if (RuleModelTypeEnum.RuleFlow.code.equals(ruleVersionVO.getModelType())
	                		  ||RuleModelTypeEnum.StrategyFlow.code.equals(ruleVersionVO.getModelType())){
	                	  kieHelper.addResource(ResourceFactory.newByteArrayResource(ruleVersionVO.getContont().getBytes()),ResourceType.BPMN2); 
	                  }else if (RuleModelTypeEnum.ExecutionBlock.code.equals(ruleVersionVO.getModelType())){
	                	  kieHelper.addResource(ResourceFactory.newByteArrayResource(ruleVersionVO.getContont().getBytes()),ResourceType.BPMN2); 
	                  }else if (RuleModelTypeEnum.CodeBlock.code.equals(ruleVersionVO.getModelType())){
	                	  continue;
	                	  //kieHelper.addResource(ResourceFactory.newByteArrayResource(ruleVersionVO.getContont().getBytes()),ResourceType.BPMN2); 
	                  }else {
	                      kieHelper.addResource(ResourceFactory.newByteArrayResource(ruleVersionVO.getContont().getBytes()),ResourceType.DRL);
	                  }
	                  drlList.add(ruleVersionVO.getDrlFile());
	                 
        		  }finally{
      
        		  }
        	  }
        	  if (drlList.size()>0){
        		  AppConfiguration.deployDrlList.put(enterPoint, drlList);
        	  }
          }
        
		  KieBaseConfiguration kbconfig = KieServices.Factory.get().newKieBaseConfiguration();
      	  kbconfig.setProperty("drools.consequenceExceptionHandler", "com.tansun.rule.exception.RuleConsequenceExceptionHandler");
		  
      	  kieBase = kieHelper.build(kbconfig);
          

	}
	
	/**
	 * 获取对象
	 */
	@Override
	public PooledObject<KieSession> wrap(KieSession session) {
		return new DefaultPooledObject<KieSession>(session);
	}
	/**
	 * 对象池对象项销毁
	 */
	@Override
	public void destroyObject(PooledObject<KieSession> p) throws Exception {
		p.getObject().destroy();
		super.destroyObject(p);
	}
	
	/**
	 * 新建对象
	 */
	public KieSession create(){
		KieSession kSession = kieBase.newKieSession();
		return kSession;
	}

}
